package maps

import "sync"

type RWMap[K comparable, V any] struct {
	sync.RWMutex
	data map[K]V
}

func (m *RWMap[K, V]) Get(key K) (V, bool) {
	m.RWMutex.RLock()
	defer m.RWMutex.RUnlock()
	v, ok := m.data[key]
	return v, ok
}

func (m *RWMap[K, V]) GetValueOnly(key K) V {
	m.RWMutex.RLock()
	defer m.RWMutex.RUnlock()
	return m.data[key]
}

func (m *RWMap[K, V]) Put(key K, value V) {
	m.RWMutex.Lock()
	defer m.RWMutex.Unlock()
	if m.data == nil {
		m.data = make(map[K]V)
	}
	m.data[key] = value
}

// PutIfNotPresent 如果当前key不存在，才进行替换操作
// 如果key已经存在，则返回false，表明插入失败
func (m *RWMap[K, V]) PutIfNotPresent(key K, value V) bool {
	m.RWMutex.Lock()
	defer m.RWMutex.Unlock()
	if m.data == nil {
		m.data = make(map[K]V)
	}
	_, exists := m.data[key]
	if !exists {
		m.data[key] = value
	}
	return !exists
}

func (m *RWMap[K, V]) Delete(key K) {
	m.RWMutex.Lock()
	defer m.RWMutex.Unlock()
	delete(m.data, key)
}

func (m *RWMap[K, V]) DeleteIfPresent(key K) bool {
	m.RWMutex.Lock()
	defer m.RWMutex.Unlock()
	_, exists := m.data[key]
	if exists {
		delete(m.data, key)
		return true
	}
	return false
}

func (m *RWMap[K, V]) Len() int {
	m.RWMutex.RLock()
	defer m.RWMutex.RUnlock()
	return len(m.data)
}

func (m *RWMap[K, V]) ForEach(fn func(k K, v V)) {
	m.RWMutex.RLock()
	defer m.RWMutex.RUnlock()
	for k, v := range m.data {
		fn(k, v)
	}
}
